<template>
    <div class="lessons">
        <div class="content">
            <el-row class="button">
                <el-button type="primary" plain @click="showGraph">查看有向图</el-button>
                <el-button type="success" plain @click="handleChangeLimitCreditClick">修改限修学分</el-button>
                <el-button plain @click="handleReturnClick">返回</el-button>
            </el-row>
            <el-table
                ref="lessonTable"
                :data="lessonData"
                tooltip-effect="dark"
                height="250"
                class="lessonTable">
                <el-table-column
                    prop="name"
                    label="课程名称"
                    width="220">
                </el-table-column>
                <el-table-column
                    prop="credit"
                    label="学分"
                    width="220">
                </el-table-column>
                <el-table-column
                    prop="term"
                    label="上课时间"
                    width="220">
                    <template slot-scope="scope">第{{scope.row.term}}学期</template>
                </el-table-column>
            </el-table>
        </div>

        <el-dialog
            title="课程先修关系图"
            :visible.sync="showGraphDialog"
            width="70%"
            class="dialog"
        >
            <div id="graph"></div>
        </el-dialog>

        <el-dialog
            title="修改限修学分"
            :visible.sync="changeLimitCreditDialogVisible"
            width="30%"
            class="dialog"
            :close-on-click-modal="false"
        >
            <el-form :model="lesson" status-icon ref="lesson" label-width="100px" class="addLessonForm">
                <el-form-item label="限修学分" prop="credit">
                    <el-input v-model="lesson.credit" placeholder="请输入每学期限修学分"></el-input>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" plain @click="changeLimitCredit">修改</el-button>
                    <el-button @click="resetForm('lesson')">重置</el-button>
                </el-form-item>
            </el-form>
        </el-dialog>
    </div>
</template>

<script>
import * as d3 from 'd3';
import axios from 'axios';
export default {
    mounted(){
        this.getLessonList();
    },
    watch: {
        showGraphDialog(val) {
            if (val) {
                this.drawGraph();
            }
        }
    },
    methods:{
        getLessonList(){
            axios({
                method:"get",
                url:"http://localhost:8080/getLessonList/"+this.$route.params.majorId,
            }).then(resp =>{
                this.lessonData=resp.data.data;
            })
        },
        handleChangeLimitCreditClick(){
            this.changeLimitCreditDialogVisible=true;
            this.resetForm('lesson');
        },
        changeLimitCredit(){
            axios({
                method:"get",
                url:"http://localhost:8080/makePlan?majorId="+this.$route.params.majorId+"&limitCredit="+this.lesson.credit,
            }).then(resp =>{
                if(resp.data.code){
                    this.$message({
                        message: '修改成功',
                        type: 'success'
                    });
                    this.changeLimitCreditDialogVisible=false;
                    this.getLessonList();
                }else{
                    this.$message({
                        message: '修改失败',
                        type: 'error'
                    });
                }
            })
        },
        showGraph(){
            axios({
                method:"get",
                url:"http://localhost:8080/showGraph?majorId="+this.$route.params.majorId,
            }).then(resp =>{
                if(resp.data.code){
                    this.showGraphDialog=true;
                    this.processGraphData(resp.data.data.vertexes);
                }else{
                    this.$message({
                        message: '查看失败',
                        type: 'error'
                    });
                }
            })
        },
        processGraphData(vertexes) {
            const nodes = [];
            const links = [];

            for (const key in vertexes) {
                //if (vertexes.hasOwnProperty(key)) {
                    const vertex = vertexes[key];
                    const lesson = this.lessonData.find(lesson => lesson.id === vertex.lessonId);
                    const lessonName = lesson ? lesson.name : `课程${vertex.lessonId}`;
                    nodes.push({ id: vertex.lessonId, name: lessonName });

                    let edge = vertex.edge;
                    while (edge) {
                        links.push({ source: vertex.lessonId, target: edge.lessonId });
                        edge = edge.next;
                    }
                //}
            }

            this.graphData = { nodes, links };
        },
        drawGraph() {
            const width = 800;
            const height = 600;

            d3.select("#graph").selectAll("*").remove(); // 清空之前的图形

            const svg = d3.select("#graph")
                .append("svg")
                .attr("width", width)
                .attr("height", height)
                .on("click", () => this.clearHighlight());

            // 定义箭头
            svg.append("defs").append("marker")
                .attr("id", "arrowhead")
                .attr("viewBox", "-0 -5 10 10")
                .attr("refX", 13)
                .attr("refY", 0)
                .attr("orient", "auto")
                .attr("markerWidth", 13)
                .attr("markerHeight", 13)
                .attr("xoverflow", "visible")
                .append("svg:path")
                .attr("d", "M 0,-5 L 10 ,0 L 0,5")
                .attr("fill", "#999")
                .style("stroke", "none");

            // 定义高亮箭头
            svg.append("defs").append("marker")
                .attr("id", "arrowhead-highlight")
                .attr("viewBox", "-0 -5 10 10")
                .attr("refX", 13)
                .attr("refY", 0)
                .attr("orient", "auto")
                .attr("markerWidth", 13)
                .attr("markerHeight", 13)
                .attr("xoverflow", "visible")
                .append("svg:path")
                .attr("d", "M 0,-5 L 10 ,0 L 0,5")
                .attr("fill", "purple")
                .style("stroke", "none");

            // 定义蓝色箭头
            svg.append("defs").append("marker")
                .attr("id", "arrowhead-blue")
                .attr("viewBox", "-0 -5 10 10")
                .attr("refX", 13)
                .attr("refY", 0)
                .attr("orient", "auto")
                .attr("markerWidth", 13)
                .attr("markerHeight", 13)
                .attr("xoverflow", "visible")
                .append("svg:path")
                .attr("d", "M 0,-5 L 10 ,0 L 0,5")
                .attr("fill", "blue")
                .style("stroke", "none");

            const link = svg.append("g")
                .attr("class", "links")
                .selectAll("line")
                .data(this.graphData.links)
                .enter().append("line")
                .attr("stroke-width", 2)
                .attr("marker-end", "url(#arrowhead)");

            const node = svg.append("g")
                .attr("class", "nodes")
                .selectAll("g")
                .data(this.graphData.nodes)
                .enter().append("g")
                .call(d3.drag()
                    .on("start", dragstarted)
                    .on("drag", dragged)
                    .on("end", dragended))
                .on("click", this.highlightNode);

            node.append("rect")
                .attr("width", 100)
                .attr("height", 40)
                .attr("fill", "#69b3a2")
                .attr("rx", 5)
                .attr("ry", 5);

            node.append("text")
                .attr("dy", 25)
                .attr("dx", 10)
                .text(d => d.name);

            const simulation = d3.forceSimulation(this.graphData.nodes)
                .force("link", d3.forceLink(this.graphData.links).id(d => d.id).distance(200))
                .force("charge", d3.forceManyBody().strength(-400))
                .force("center", d3.forceCenter(width / 2, height / 2));

            simulation
                .nodes(this.graphData.nodes)
                .on("tick", ticked);

            simulation.force("link")
                .links(this.graphData.links);

            function ticked() {
                link
                    .attr("x1", d => d.source.x + 50)
                    .attr("y1", d => d.source.y + 20)
                    .attr("x2", d => d.target.x + 50)
                    .attr("y2", d => d.target.y + 20);

                node
                    .attr("transform", d => `translate(${d.x},${d.y})`);
            }

            function dragstarted(event, d) {
                if (!event.active) simulation.alphaTarget(0.3).restart();
                d.fx = d.x;
                d.fy = d.y;
            }

            function dragged(event, d) {
                d.fx = event.x;
                d.fy = event.y;
            }

            function dragended(event, d) {
                if (!event.active) simulation.alphaTarget(0);
                d.fx = null;
                d.fy = null;
            }
        },
        highlightNode(event, d) {
            event.stopPropagation();

            const svg = d3.select("#graph svg");
            svg.selectAll("rect").attr("fill", "#69b3a2");
            svg.selectAll("line").attr("stroke", "#999").attr("marker-end", "url(#arrowhead)");

            d3.select(event.currentTarget).select("rect").attr("fill", "red");

            const connectedNodes = this.graphData.links.filter(link => link.source.id === d.id || link.target.id === d.id);
            connectedNodes.forEach(link => {
                if (link.source.id === d.id) {
                    svg.selectAll("line")
                        .filter(l => l.source.id === link.source.id && l.target.id === link.target.id)
                        .attr("stroke", "purple")
                        .attr("marker-end", "url(#arrowhead-highlight)");

                    svg.selectAll("rect")
                        .filter(node => node.id === link.target.id)
                        .attr("fill", "purple");
                } else if (link.target.id === d.id) {
                    svg.selectAll("line")
                        .filter(l => l.source.id === link.source.id && l.target.id === link.target.id)
                        .attr("stroke", "blue")
                        .attr("marker-end", "url(#arrowhead-blue)");

                    svg.selectAll("rect")
                        .filter(node => node.id === link.source.id)
                        .attr("fill", "blue");
                }
            });
        },
        clearHighlight() {
            const svg = d3.select("#graph svg");
            svg.selectAll("rect").attr("fill", "#69b3a2");
            svg.selectAll("line").attr("stroke", "#999").attr("marker-end", "url(#arrowhead)");
        },
        toggleSelection(rows) {
            if (rows) {
            rows.forEach(row => {
                this.$refs.multipleTable.toggleRowSelection(row);
            });
            } else {
            this.$refs.multipleTable.clearSelection();
            }
        },
        handleReturnClick(){
            this.$router.push({path:'/major'});
        },
        // 重置方法
        resetForm(formName) {
            this.$refs[formName].resetFields();
        },
    },
    data() {
      return {
        changeLimitCreditDialogVisible: false,
        showGraphDialog: false,
        lessonData: [],
        multipleSelection: [],
        lesson: {
            id: '',
            name: '',
            credit: '',
            term: '',
        },
        graphData: {
            nodes: [],
            links: [],
        },
      }
    },
}
</script>

<style scoped>
.lessons {
    background-image: url('@/assets/GDUT.jpg');
    background-size: cover;
    background-position: center;
    height: 100vh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    color: white;
    text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
    text-align: center;
    margin-top: 50px;
    margin: 0;
    padding: 0;
    overflow: hidden;
}

.content {
    background-color: rgba(255, 255, 255, 0.8);
    padding: 80px;
    border-radius: 40px;
    text-align: center;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    color: #333;
}

.button {
    text-align: left;
}


.lessonTable {
    width: 100%; /* 设置表格宽度 */
    height: 500px; /* 设置表格高度 */
    margin: 0 auto; /* 居中对齐 */
}

#graph {
    width: 100%;
    height: 100%;
}

.links line {
    stroke: #999;
    stroke-opacity: 0.6;
}

.nodes rect {
    stroke: #fff;
    stroke-width: 1.5px;
}

.texts text {
    fill: #000;
    font-size: 12px;
    pointer-events: none;
}

</style>